package com.renjun.smweb.commons.componet;


import com.renjun.smweb.annotation.AuthorityDeclaration;
import com.renjun.smweb.commons.global.DataDict;
import com.renjun.smweb.commons.global.DynamicCache;
import com.renjun.smweb.commons.global.ExceptionDict;
import com.renjun.smweb.commons.global.StaticCaches;
import com.renjun.smweb.commons.util.ClassScans;
import com.renjun.smweb.commons.util.CollectionUtils;
import com.renjun.smweb.commons.util.JdbcProperties;
import com.renjun.smweb.dao.bean.*;
import com.renjun.smweb.dao.pojo.CurrentTermInfo;
import com.renjun.smweb.service.PermissionService.PermissionService;
import com.renjun.smweb.commons.util.ClassScans;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by Rio-Lee on 2016/6/16.
 * 初始化数据组件
 */
@Component
public class InitComponent implements InitializingBean {

    private static boolean isInitializing = false;

    @Resource
    private BaseDaoComponent baseDaoComponent;
    @Resource
    private PermissionService permissionService;
    @Resource
    private FileIOComponent fileIOComponent;

    /**
     * 加载初始化数据
     */
    public void loadInitData() throws Exception {
        //加载JDBC数据库
        loadJdbcSource();
        //加载文件类型地址信息
        reloadFileTypes();
        // 加载区县字典
        loadDistrictCache();
        // 加载菜单缓存
        reloadMenuListCache();
        //加载当前学期
        loadCurrentTerm();
        // 加载数据字典
        reloadDataDictCache();
        // 加载异常信息字典缓存
        reloadExceptionDictCache();
        //加载功能列表
        loadFunctionUrlDict();

        List<Map<String, Object>> roleMenus = permissionService.queryAllRoleMenus();
        List<Map<String, Object>> roleFunctions = permissionService.queryAllRoleFuncs();
//        List<Map<String, Object>> roleDataAreas = permissionService.queryAllRoleDataAreas();//数据范围
//        StaticCaches.loadAllDataAreas(CollectionUtils.converMapKeyToLowerCase(roleDataAreas));
        StaticCaches.loadAllFuncs(CollectionUtils.converMapKeyToLowerCase(roleFunctions));
        StaticCaches.loadByMenuList(CollectionUtils.converMapKeyToLowerCase(roleMenus));
        StaticCaches.setJiamSwitch(3);  //加密开关 1(全部加密),2(全部不加密),3(按照程序默认)

        //TODO 需要注释此接口
        //删除所有接口信息
//        reloadRequestMapping();
        //插入接口信息进t_funcurlinfo
        loadRequestMapping();



        isInitializing = true;
        System.out.println("初始化数据完成");
    }

    //加载当前学期
    private void loadCurrentTerm() throws SQLException {
        QueryParams queryCurrentTerm = QueryParams.createQueryParams("t_terminfo");
        queryCurrentTerm.addQueryParams(Parameter.createParameter("currentterm", "1"));
        List<Map<String, Object>> currTerms = baseDaoComponent.selectDataByParams(queryCurrentTerm);
        CurrentTermInfo cti = new CurrentTermInfo(currTerms.get(0));
        StaticCaches.setCurrentTerm(cti);
    }

    //加载异常信息字典缓存
    private void reloadExceptionDictCache() throws IOException {
        ExceptionDict.loadProperties(this.getClass().getResourceAsStream("/exceptions.properties"));
    }

    //加载文件类型地址信息
    private void reloadFileTypes() throws SQLException {
        fileIOComponent.reloadFileTypes();
    }

    /**
     * 加载数据字典缓存
     *
     * @throws SQLException
     */
    public void reloadDataDictCache() throws SQLException {
        List<Map<String, Object>> dictList = baseDaoComponent.selectDataByParams(QueryParams.createQueryParams("vf_all_bz_map"));
        DataDict.initLoadDataDicts(CollectionUtils.converMapKeyToLowerCase(dictList));
    }

    /**
     * 加载菜单列表缓存
     *
     * @throws SQLException
     */
    public void reloadMenuListCache() throws SQLException {
        List<Map<String, Object>> menuList = baseDaoComponent.selectDataByParams(QueryParams.createQueryParams("v_role_menus"));
        StaticCaches.loadByMenuList(CollectionUtils.converMapKeyToLowerCase(menuList));
    }


    private static void addLists(List dest, List... args) {
        for (List list : args) {
            dest.addAll(list);
        }
    }

    //查所有区县
    private void loadDistrictCache() throws SQLException {
        QueryParams queryDistrictCache = QueryParams.createQueryParams("T_BZ_DISTRICT");
        List<Map<String, Object>> data = baseDaoComponent.selectDataByParams(queryDistrictCache);
        DynamicCache.loadDistrictCache(data);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (isInitializing) return;
        loadInitData();
    }

    //加载数据库
    private void loadJdbcSource() {//TODO 记得配置jdbc.properties
        //test93--93数据库
        JdbcProperties.jdbcSource = "test93";
//        JdbcProperties.jdbcSource = "local";
        //服务器操作平台--windows/linux
        JdbcProperties.serverType = "windows";
//        JdbcProperties.serverType = "linux";

        loadRedisConfig();//加载REDIS
        loadDBCPconnectionPool();//加载DBCPConnectionPool数据库配置文件
        loadDbutilsJdbcSource();//加载Dbutils数据库配置文件
        loadDBPoolJdbcSource();//加载DBPool数据库配置文件
    }

    //加载REDIS
    private void loadRedisConfig() {
        if ("test93".equals(JdbcProperties.jdbcSource)) {
            RedisComponent.redisSource="test92_";
        }
    }

    //加载DBCPconnectionPool数据库
    private void loadDBCPconnectionPool() {
        if ("test93".equals(JdbcProperties.jdbcSource)) {
            JdbcProperties.DBCPCONPOOL_MASTERCONFIG = "test93_master.properties";
            JdbcProperties.DBCPCONPOOL_SBCONFIG = "test93_sb.properties";
            JdbcProperties.DBCPCONPOOL_JSSBCONFIG = "test93_jssb.properties";
            JdbcProperties.DBCPCONPOOL_XFCONFIG = "test93_xf.properties";
        }
    }

    //加载Dbutils数据库
    private void loadDbutilsJdbcSource() {
        if ("test93".equals(JdbcProperties.jdbcSource)) {
            JdbcProperties.DBUTILS_MASTER_URL = "jdbc:oracle:thin:@61.151.214.93:1521:orcl";
            JdbcProperties.DBUTILS_MASTER_USR = "xjxtuser";
            JdbcProperties.DBUTILS_MASTER_PWD = "xjxtuser";
            JdbcProperties.DBUTILS_SB_URL = "jdbc:oracle:thin:@61.151.214.93:1521:orcl";
            JdbcProperties.DBUTILS_SB_USR = "xjxtuser";
            JdbcProperties.DBUTILS_SB_PWD = "xjxtuser";
            JdbcProperties.DBUTILS_XF_URL = "jdbc:oracle:thin:@61.151.214.93:1521:orcl";
            JdbcProperties.DBUTILS_XF_USR = "xjxtuserxf";
            JdbcProperties.DBUTILS_XF_PWD = "xjxtuserxf";
        }
    }

    //加载DBPool数据库
    private static void loadDBPoolJdbcSource() {
        if ("test93".equals(JdbcProperties.jdbcSource)) {
            JdbcProperties.DBPool_msurl = "test93ms.url";
            JdbcProperties.DBPool_msusr = "test93ms.usr";
            JdbcProperties.DBPool_mspwd = "test93ms.pwd";
            JdbcProperties.DBPool_msmin = "test93ms.min";
            JdbcProperties.DBPool_msmax = "test93ms.max";
            JdbcProperties.DBPool_mstimeout = "test93ms.timeout";
            JdbcProperties.DBPool_sburl = "test93sb.url";
            JdbcProperties.DBPool_sbusr = "test93sb.usr";
            JdbcProperties.DBPool_sbpwd = "test93sb.pwd";
            JdbcProperties.DBPool_sbmin = "test93sb.min";
            JdbcProperties.DBPool_sbmax = "test93sb.max";
            JdbcProperties.DBPool_sbtimeout = "test93sb.timeout";
            JdbcProperties.DBPool_xfurl = "test93xf.url";
            JdbcProperties.DBPool_xfusr = "test93xf.usr";
            JdbcProperties.DBPool_xfpwd = "test93xf.pwd";
            JdbcProperties.DBPool_xfmin = "test93xf.min";
            JdbcProperties.DBPool_xfmax = "test93xf.max";
            JdbcProperties.DBPool_xftimeout = "test93xf.timeout";
        }
    }

    public void loadRequestMapping() throws SQLException {
        List<Class<?>> cls = ClassScans.getClassList("com.dianda.yeyzsxj.controller.AdminController", true, Controller.class);
        List<Class<?>> cls2 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.AdmissionController", true, Controller.class);
        List<Class<?>> cls3 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.EnrollmentController", true, Controller.class);
        List<Class<?>> cls4 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.HomestatisticsController1", true, Controller.class);
        List<Class<?>> cls5 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.NoticeController", true, Controller.class);
        List<Class<?>> cls6 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.PermissionController", true, Controller.class);
        List<Class<?>> cls7 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.RegisterController", true, Controller.class);
        List<Class<?>> cls8 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.RoleController", true, Controller.class);
        List<Class<?>> cls9 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.SchoolController", true, Controller.class);
        List<Class<?>> cls10 = ClassScans.getClassList("com.dianda.yeyzsxj.controller", false, Controller.class);

        List<Class<?>> cls11 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.FileController", true, Controller.class);
        List<Class<?>> cls12 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.StatisticsController", true, Controller.class);
        List<Class<?>> cls13 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.NewsController", true, Controller.class);
        List<Class<?>> cls14 = ClassScans.getClassList("com.dianda.yeyzsxj.controller.InterfaceController", true, Controller.class);



        addLists(cls, cls2, cls3, cls4, cls5, cls6, cls7, cls8, cls9,cls11,cls12,cls13,cls14 ,cls10);
        /*ExportDocument ed = ExportDocument.createNewInstance("/storage/urldoc/urldoc.xlsx");
        try {
            ed.writeClassListDocument(cls);
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        for (Class clz : cls) {
            RequestMapping crm = (RequestMapping) clz.getAnnotation(RequestMapping.class);
            List<Method> methods = ClassScans.getMethodList(clz, RequestMapping.class);
            if (methods != null) {
                for (Method method : methods) {
                    RequestMapping rm = method.getAnnotation(RequestMapping.class);
                    AuthorityDeclaration ad = method.getAnnotation(AuthorityDeclaration.class);
                    if (rm != null && ad != null) {
                        String url = rm.value()[0];
                        if (crm != null) url = crm.value()[0] + url;
                        QueryParams queryParams = QueryParams.createQueryParams("t_funcurlinfo");
                        queryParams.addQueryParams(Parameter.createParameter("URL", url));
                        List<Map<String, Object>> result = baseDaoComponent.selectDataByParams(queryParams);
                        String desc = ad.desc();
                        String id = ad.id();
                        if (result != null && result.size() > 0) {
                            UpdateParams updateFunc = UpdateParams.createUpdateParams("t_funcurlinfo");
                            updateFunc.addParams(Parameter.createParameter("name", desc));
                            updateFunc.addWhereParameter(Parameter.createParameter("url", url));
                            baseDaoComponent.updateDataByParams(updateFunc);
                            continue;
                        }
                        InsertParams insertParams = InsertParams.createInsertParams("t_funcurlinfo", "ID", "URL", "NAME", "\"DESC\"", "STATUS", "ADDTIME");
                        insertParams.setValues(id, url, desc, desc, '0', new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
                        insertParams.printSelf();
                        baseDaoComponent.insertDataByParams(insertParams);
                    }
                }
            }
        }
    }

    //加载功能列表
    private void loadFunctionUrlDict() throws SQLException {
        QueryParams queryUrlDict = QueryParams.createQueryParams("T_FUNCURLINFO");
        List<Map<String, Object>> urlDictList = baseDaoComponent.selectDataByParams(queryUrlDict);
        for (Map<String, Object> urlDict : urlDictList) {
            String url = (String) urlDict.get("url");
            String name = (String) urlDict.get("name");
            StaticCaches.putUrlDict(url, name);
        }
    }

    //删除所有接口信息
    public void reloadRequestMapping() throws SQLException {
        DeleteParams deleteParams = DeleteParams.createDeleteParams("t_funcurlinfo", Parameter.createParameter("1", 1));
        baseDaoComponent.deleteDataByParams(deleteParams);
        loadRequestMapping();
    }

}
